#include <fhepython/PyNodeDesc.h>
#include <fhepython/PyFuncDesc.h>
#include <fhepython/PyVarDesc.h>
#include <fhepython/PyEnv.h>
#include <fhe/core/Node.h>

namespace fhe
{
  namespace python
  {
    PyNodeDesc::PyNodeDesc( boost::python::object base )
      : base_( base )
    {
      boost::python::dict dict( base_.attr( "__dict__" ) );
      boost::python::list keys( dict.iterkeys() );
      for ( int i = 0; i < boost::python::len( keys ); ++i )
      {
        std::string name = boost::python::extract<std::string>( keys[i] );
        boost::python::object func = dict[name];
        if ( ( name == "__init__" || name.substr( 0, 2 ) != "__" ) && PyEnv::instance().callable( func ) )
        {
          addFunc( IFuncDesc::Ptr( new PyFuncDesc( func ) ) );
          if ( name.substr( 0, 4 ) == "get_" )
          {
            std::string setName = "set_" + name.substr( 4 );
            if ( dict.attr( "__contains__" )( setName ) )
            {
              addVar( IVarDesc::Ptr( new PyVarDesc( name.substr( 4 ), func, dict[ setName ] ) ) );
            }
            else
            {
              addVar( IVarDesc::Ptr( new PyVarDesc( name.substr( 4 ), func, boost::python::object() ) ) );
            }
          }
        }
      }
    }
    
    Node* PyNodeDesc::build() const
    {
      Node* node = new Node;
      INodeDesc::build( node );
      if ( node->hasFunc( "__init__" ) )
      {
        node->call( "__init__" );
      }
      return node;
    }
  }
}
